package edu.cibertec.sicsolutions.vfs.spring;

import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.ibatis.SqlMapClientCallback;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.ibatis.sqlmap.client.SqlMapExecutor;

import edu.cibertec.sicsolutions.util.ClassUtil;
import edu.cibertec.sicsolutions.util.StringUtil;

/**
 * Clase Base para las Clases Dao Spring
 * 
 */
public class SpringIbatisBase extends SqlMapClientDaoSupport {	
	
	/** log disponible para todas las subclases **/
	public Logger log = Logger.getLogger(getClass());
	
	public boolean isLogginEnabled() {
		return log.isDebugEnabled();
	}
	
	private boolean started = false;
	
	public void init(){
		if (!started) {
			getSqlMapClientTemplate();
			started = true;
		}		
	}
	
	/** Clase que genera el log de los statement
	 * @param statementName
	 * @param startTime
	 * @param endTime
	 */
/*	private void logging(String statementName, long startTime, long endTime){		
		log.debug(new StringBuffer()
		.append(" execute statementName [").append(statementName).append("]")
		.append(" start [").append(startTime).append("]")
		.append(" finish [").append(endTime).append("]")
		.append(" totalTime [").append(endTime-startTime).append("]"));
	}*/
	
	private String getKeyStatement(String statementName){
		String className = ClassUtil.getShortClassName(this.getClass());
		String pack = ClassUtil.getPackageName(this.getClass());
		String[] array = StringUtil.split(pack, '.');
		String result = array[array.length-2]+"."+className.substring(0, className.length()-7) + "." + statementName;		
		return result;
	}
	
	/** 
	 * Metodo para hacer update en batch
	 * <pre>
	 * List list = new ArrayList();
	 * list.add(domain1);
	 * list.add(domain2);
	 * updateInBatch("updateDomain", list);
	 * </pre>
	 * @param statementName
	 * @param parameterList
	 */
	public void updateInBatch(final String statementName, final List parameterList){
		/*long startTime = System.currentTimeMillis();*/
		getSqlMapClientTemplate().execute(new SqlMapClientCallback(){
			public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
				executor.startBatch();
				for (Iterator iterator = parameterList.iterator(); iterator.hasNext();) {
					executor.update(getKeyStatement(statementName), (Object) iterator.next());
				}
				executor.executeBatch();
				return null;
			}			
		}
		);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}*/
	}
	
	/** 
	 * Metodo para hacer insert en batch
	 * <pre>
	 * List list = new ArrayList();
	 * list.add(domain1);
	 * list.add(domain2);
	 * insertInBatch("updateDomain", list);
	 * </pre>
	 * @param statementName
	 * @param parameterList
	 */
	public void insertInBatch(final String statementName, final List parameterList){
		/*long startTime = System.currentTimeMillis();*/
		getSqlMapClientTemplate().execute(new SqlMapClientCallback(){
			public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
				executor.startBatch();
				for (Iterator iterator = parameterList.iterator(); iterator.hasNext();) {
					Object parameterObject = (Object) iterator.next();
					executor.insert(getKeyStatement(statementName), parameterObject);
				}
				executor.executeBatch();
				return null;
			}			
		}
		);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}*/
	}

	public void delete(String statementName, Object parameterObject, int requiredRowsAffected)
			throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		getSqlMapClientTemplate().delete(getKeyStatement(statementName), parameterObject, requiredRowsAffected);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}*/
	}

	public int delete(String statementName, Object parameterObject) throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().delete(getKeyStatement(statementName), parameterObject);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public int delete(String statementName) throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().delete(getKeyStatement(statementName));
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public Object execute(SqlMapClientCallback arg0) throws DataAccessException {
		return getSqlMapClientTemplate().execute(arg0);
	}

	public List executeWithListResult(SqlMapClientCallback action) throws DataAccessException {
		return getSqlMapClientTemplate().executeWithListResult(action);
	}

	public Map executeWithMapResult(SqlMapClientCallback action) throws DataAccessException {
		return getSqlMapClientTemplate().executeWithMapResult(action);
	}

	public Object insert(String statementName, Object parameterObject) throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().insert(getKeyStatement(statementName), parameterObject);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public Object insert(String statementName) throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().insert(getKeyStatement(statementName));
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public List queryForList(String statementName, int skipResults, int maxResults)
			throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().queryForList(getKeyStatement(statementName), skipResults, maxResults);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public List queryForList(String statementName, Object parameterObject, int skipResults,
			int maxResults) throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().queryForList(getKeyStatement(statementName), parameterObject, skipResults, maxResults);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public List queryForList(String statementName, Object parameterObject)
			throws DataAccessException {		
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().queryForList(getKeyStatement(statementName), parameterObject);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public List queryForList(String statementName) throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().queryForList(getKeyStatement(statementName));
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public Map queryForMap(String statementName, Object parameterObject, String keyProperty,
			String valueProperty) throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().queryForMap(getKeyStatement(statementName), parameterObject, keyProperty, valueProperty);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public Map queryForMap(String statementName, Object parameterObject, String keyProperty)
			throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().queryForMap(getKeyStatement(statementName), parameterObject, keyProperty);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public Object queryForObject(String statementName, Object parameterObject, Object resultObject)
			throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().queryForObject(getKeyStatement(statementName), parameterObject, resultObject);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public Object queryForObject(String statementName, Object parameterObject)
			throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().queryForObject(getKeyStatement(statementName), parameterObject);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public Object queryForObject(String statementName) throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().queryForObject(getKeyStatement(statementName));
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public void update(String statementName, Object parameterObject, int requiredRowsAffected)
			throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		getSqlMapClientTemplate().update(getKeyStatement(statementName), parameterObject, requiredRowsAffected);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}*/
	}

	public int update(String statementName, Object parameterObject) throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().update(getKeyStatement(statementName), parameterObject);
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

	public int update(String statementName) throws DataAccessException {
		/*long startTime = System.currentTimeMillis();*/
		return getSqlMapClientTemplate().update(getKeyStatement(statementName));
/*		if (isLogginEnabled()) {
			logging(getKeyStatement(statementName), startTime, System.currentTimeMillis());
		}
		return result;*/
	}

}
